package com.kalaqia.icon.font.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.support.annotation.ArrayRes;
import android.support.annotation.ColorInt;
import android.support.annotation.FontRes;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.widget.AppCompatTextView;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.Toast;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;

/**
 * @author kalaqia 421407393@qq.com
 */
public class IconFontTextView extends AppCompatTextView {

    private String textValue;

    private final String FORMAT_ICON_VERTICAL;
    private final String FORMAT_ICON_HORIZONTAL;


    public IconFontTextView(Context context) {
        this(context, null);
    }

    public IconFontTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public IconFontTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        FORMAT_ICON_VERTICAL = "%s\n%s";
        FORMAT_ICON_HORIZONTAL = "%s %s";
        setGravity(Gravity.CENTER);
        initAttributeSet(context, attrs);
        initListener();
    }

    protected void initListener() {
        setOnClickListener(v -> setSelected(!isSelected()));
    }

    @Override
    public void setTextSize(float size) {
        super.setTextSize(size);
    }

    @SuppressWarnings("WrongConstant")
    protected void initAttributeSet(Context context, AttributeSet attrs) {

        TypedArray attr = context.obtainStyledAttributes(attrs, R.styleable.IconFontTextView, 0, 0);
        if (attrs == null || attr == null) {
            return;
        }

        try {
            this.icon = attr.getString(R.styleable.IconFontTextView_textIcon);
            this.textValue = attr.getString(R.styleable.IconFontTextView_textValue);

//            if (TextUtils.isEmpty(this.textValue)) {
//                this.textValue = getText().toString().trim();
//            }
            this.curIconType = attr.getInt(R.styleable.IconFontTextView_drawType, initByType(attr));
//
////            setTextColor(attr.getColor(R.styleable.IconFontTextView_iconColor, getCurrentTextColor()));
////            setTextValueColor(attr.getColor(R.styleable.IconFontTextView_textValueColor, getCurrentHintTextColor()));
//
//            iconColor = attr.getColor(R.styleable.IconFontTextView_iconColor, getCurrentTextColor());
//            textValueColor = attr.getColor(R.styleable.IconFontTextView_textValueColor, getCurrentTextColor());
//
//            iconSize = attr.getDimensionPixelSize(R.styleable.IconFontTextView_iconSize, (int) getTextSize());
//
            //set icon font typeface
            int fontResourceId = attr.getResourceId(R.styleable.IconFontTextView_iconFontFamily, 0);
            if (!isInEditMode() && fontResourceId != 0) {
                setIconTypeface(fontResourceId);
            }
////
            initDraw();

        } finally {
            attr.recycle();
        }
    }

//    public void setTextValueColor(Integer textValueColor) {
//        this.textValueColor = textValueColor;
//
//        SpannableStringBuilder span = new SpannableStringBuilder(getText().toString().trim());
//
//        switch (curIconType) {
//            case ICON_TYPE_RIGHT:
//                if (textValueColor != null)
//                    span.setSpan(new ForegroundColorSpan(textValueColor), 0, this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//                setText(span);
//                break;
//            case ICON_TYPE_BOTTOM:
//                break;
//            case ICON_TYPE_LEFT:
////                if (iconColor != null)
////                    span.setSpan(new ForegroundColorSpan(iconColor), 0, str.length() - this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
////                if (textValueColor != null)
////                    span.setSpan(new ForegroundColorSpan(textValueColor), str.length() - this.textValue.length(), str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
////                if (iconSize != null)
////                    span.setSpan(new AbsoluteSizeSpan(iconSize), 0, str.length() - this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//                break;
//            case ICON_TYPE_SELECTOR:
//                break;
//            case ICON_TYPE_SINGLE:
////                setText(this.icon);
////                setTextSize(this.iconSize);
//                break;
//            case ICON_TYPE_TOP:
////                str = String.format(FORMAT_ICON_VERTICAL, this.icon, this.textValue);
////                span = new SpannableStringBuilder(str);
////
////                if (iconColor != null)
////                    span.setSpan(new ForegroundColorSpan(iconColor), 0, str.length() - this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
////                if (textValueColor != null)
////                    span.setSpan(new ForegroundColorSpan(textValueColor), str.length() - this.textValue.length(), str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
////                if (iconSize != null)
////                    span.setSpan(new AbsoluteSizeSpan(iconSize), 0, str.length() - this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//                break;
//            case ICON_TYPE_NONE:
//            default:
//                break;
//        }
//    }

    @IconType
    private int initByType(TypedArray attr) {
        String icon;
        icon = attr.getString(R.styleable.IconFontTextView_drawIconLeft);
        if (!TextUtils.isEmpty(icon)) {
            this.icon = icon;
            return ICON_TYPE_LEFT;
        }
        icon = attr.getString(R.styleable.IconFontTextView_drawIconRight);
        if (!TextUtils.isEmpty(icon)) {
            this.icon = icon;
            return ICON_TYPE_RIGHT;
        }
        icon = attr.getString(R.styleable.IconFontTextView_drawIconTop);
        if (!TextUtils.isEmpty(icon)) {
            this.icon = icon;
            return ICON_TYPE_TOP;
        }
        icon = attr.getString(R.styleable.IconFontTextView_drawIconBottom);
        if (!TextUtils.isEmpty(icon)) {
            this.icon = icon;
            return ICON_TYPE_BOTTOM;
        }

        if (this.icon != null && this.textValue == null) {
            return ICON_TYPE_SINGLE;
        }

        return ICON_TYPE_NONE;
    }

    protected void initDraw() {
        SpannableStringBuilder span = null;
        String str;

        switch (curIconType) {
            case ICON_TYPE_RIGHT:
                str = String.format(FORMAT_ICON_HORIZONTAL, this.textValue, this.icon);
                span = new SpannableStringBuilder(str);
//                if (iconColor != null)
//                    span.setSpan(new ForegroundColorSpan(iconColor), this.textValue.length() + 1, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//                if (textValueColor != null)
//                    span.setSpan(new ForegroundColorSpan(textValueColor), 0, this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                if (iconSize != 0) {
                    span.setSpan(new AbsoluteSizeSpan(iconSize), this.textValue.length() + 1, str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                break;
            case ICON_TYPE_BOTTOM:
                str = String.format(FORMAT_ICON_VERTICAL, this.textValue, this.icon);
                span = new SpannableStringBuilder(str);
                break;
            case ICON_TYPE_LEFT:
                str = String.format(FORMAT_ICON_HORIZONTAL, this.icon, this.textValue);
                span = new SpannableStringBuilder(str);
//                if (iconColor != null)
//                    span.setSpan(new ForegroundColorSpan(iconColor), 0, str.length() - this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//                if (textValueColor != null)
//                    span.setSpan(new ForegroundColorSpan(textValueColor), str.length() - this.textValue.length(), str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                if (iconSize != 0) {
                    span.setSpan(new AbsoluteSizeSpan(iconSize), 0, str.length() - this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                break;
//            case ICON_TYPE_SELECTOR:
//                break;
//            case ICON_TYPE_SINGLE:
//                setText(this.icon);
//                setTextSize(TypedValue.COMPLEX_UNIT_PX, this.iconSize);
//                break;
            case ICON_TYPE_TOP:
                str = String.format(FORMAT_ICON_VERTICAL, this.icon, this.textValue);
                span = new SpannableStringBuilder(str);
//                if (iconColor != null)
//                    span.setSpan(new ForegroundColorSpan(iconColor), 0, str.length() - this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//                if (textValueColor != null)
//                    span.setSpan(new ForegroundColorSpan(textValueColor), str.length() - this.textValue.length(), str.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                if (iconSize != 0) {
                    span.setSpan(new AbsoluteSizeSpan(iconSize), 0, str.length() - this.textValue.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                break;
            case ICON_TYPE_NONE:
            default:
                break;
        }
        if (span != null) {
            setText(span);
        }
    }

    public IconFontTextView setTextValue(String textValue) {
        this.textValue = textValue;
        return this;
    }

//    @Override
//    public void setTextColor(@ColorInt int color) {
//        super.setTextColor(color);
//        this.iconColor = color;
//    }

    public void setTextValueColor(@ColorInt int color) {
        this.textValueColor = color;
    }

    private String icon;
    @ColorInt
    private Integer iconColor;
    @ColorInt
    private Integer textValueColor;
    private int iconSize;

    @IconType
    private int curIconType = ICON_TYPE_NONE;

    public static final int ICON_TYPE_NONE = 0;
    public static final int ICON_TYPE_SINGLE = 1;
    public static final int ICON_TYPE_LEFT = 2;
    public static final int ICON_TYPE_TOP = 3;
    public static final int ICON_TYPE_RIGHT = 4;
    public static final int ICON_TYPE_BOTTOM = 5;
    public static final int ICON_TYPE_SELECTOR = 6;

    @RestrictTo(LIBRARY_GROUP)
    @IntDef({ICON_TYPE_NONE, ICON_TYPE_SINGLE, ICON_TYPE_LEFT, ICON_TYPE_TOP, ICON_TYPE_RIGHT, ICON_TYPE_BOTTOM, ICON_TYPE_SELECTOR})
    @Retention(RetentionPolicy.SOURCE)
    @interface IconType {
    }

    private String[] strSelector;

    public void drawTextSelector(String[] strSelector) {
        this.strSelector = strSelector;
        setSelected(isSelected());
    }

    public void drawTextSelector(@ArrayRes int res) {
        if (res == 0) {
            this.strSelector = null;
            return;
        }
//        drawTextSelector(getResources().getStringArray(res));
    }

    @Override
    public void setSelected(boolean selected) {
        super.setSelected(selected);
        if (strSelector != null) {
            curIconType = ICON_TYPE_SELECTOR;
            setText(strSelector[selected ? 1 : 0]);
        }
    }

    public void drawIconTop(@NonNull String icon) {
        try {
            checkIconTypeface();
            this.icon = icon;
            curIconType = ICON_TYPE_TOP;
            initDraw();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void drawIconRight(@NonNull String icon) {
        try {
            checkIconTypeface();
            this.icon = icon;
            curIconType = ICON_TYPE_RIGHT;
            initDraw();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void drawIconLeft(@NonNull String icon) {
        try {
            checkIconTypeface();
            this.icon = icon;
            curIconType = ICON_TYPE_LEFT;
            initDraw();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @FontRes
    private Integer iconTypeface;

    private void checkIconTypeface() throws Exception {
        if (iconTypeface == null) {
//            Toast.makeText(getContext(), "未设置icon font资源", Toast.LENGTH_SHORT).show();
            throw new Exception("未设置icon font资源");
        }
    }

    @SuppressWarnings("UnusedReturnValue")
    public IconFontTextView setIconTypeface(@FontRes int resId) {
        this.iconTypeface = resId;
        Typeface typeface = ResourcesCompat.getFont(getContext(), resId);
        if (typeface != null) {
            setTypeface(typeface);
        }
        return this;
    }

    public static class Builder {

        private final IconFontTextView view;

        public Builder(Context context) {
            view = new IconFontTextView(context);
        }

        public Builder setType(@IconType int type) {
            view.curIconType = type;
            return this;
        }

        public Builder setIcon(String icon) {
            view.icon = icon;
            return this;
        }

        public Builder setIconSize(int size) {
            view.iconSize = size;
            return this;
        }

        public Builder setTextValue(String textValue) {
            view.textValue = textValue;
            return this;
        }

        public Builder setTextSize(int size) {
            view.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
            return this;
        }

        public Builder setIconColor(int iconColor) {
            view.iconColor = iconColor;
            return this;
        }

        public Builder setTextValueColor(int textValueColor) {
            view.textValueColor = textValueColor;
            return this;
        }

        public Builder setIconTypeface(@FontRes int resId) {
            view.setIconTypeface(resId);
            return this;
        }

        public IconFontTextView build() {
            view.initDraw();
            return view;
        }

    }


}
